package com.zyg.seckill.service.impl;

import com.alibaba.fastjson.JSON;
import com.zyg.common.entity.PayVo;
import com.zyg.seckill.entity.SeckillStatus;
import com.zyg.seckill.entity.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyg.seckill.entity.TbSeckillOrder;
import com.zyg.seckill.dao.TbSeckillOrderMapper;
import com.zyg.seckill.service.TbSeckillOrderService;
/**
 * Created by WF on 2021/11/25 14:57
 */
@Service
public class TbSeckillOrderServiceImpl extends ServiceImpl<TbSeckillOrderMapper, TbSeckillOrder> implements TbSeckillOrderService{
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MultiThreadingCreateOrder threadingCreateOrder;
    //1. 保存订单
    @Override
    public boolean saveOrder(String secKillId, String username, String time) {
        //1.1 定义订单状态对象
        SeckillStatus seckillStatus = new SeckillStatus(username,new Date(),1,new Long(secKillId),time);

        //第一件事:避免重复下单
        //1.2 为了避免重复下单,我们可以指定一个固定大key,以当前用户名为小key,自增1
        Long count = redisTemplate.boundHashOps("UserQueueCount").increment(username, 1);
        if(count > 1){
            throw new RuntimeException(StatusCode.REPERROR + "");       //复复排队异常
        }
        //第二件事:为了公平起见,先到先买,我们可以将用户状态值放到List集合(左进右出),但是,一旦它的数据出了list就不再有了,所以,要备份它
        redisTemplate.boundListOps("SeckillOrderQueue").leftPush(JSON.toJSONString(seckillStatus));

        //第三件事:备份订单状态值
        redisTemplate.boundHashOps("UserQueueStatus").put(username,JSON.toJSONString(seckillStatus));


        //第四件事: 开始异步下单
        threadingCreateOrder.createOrder();
        return true;
    }


    @Override
    public PayVo findPayVo(String username) {
        String orderStr = (String) redisTemplate.boundHashOps("SeckillOrder").get(username);
        TbSeckillOrder orderEntity = JSON.parseObject(orderStr, TbSeckillOrder.class);
        PayVo payVo = new PayVo();
        payVo.setOut_trade_no(orderEntity.getId() + "");
        payVo.setTotal_amount(orderEntity.getMoney() + "");
        payVo.setSubject("秒杀订单");
        payVo.setBody("泽易购秒杀");

        return payVo;
    }
}
